package com.jake.xfeed.recyclerfeed;

import android.graphics.Rect;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public abstract class BaseCardExposeChecker<Data> {
    public static int MIN_CARD_HEIGHT = 2;
    private Map<String, WeakReference<Data>> sExposures = new HashMap<>();


    public void onScrollEnd(RecyclerView recyclerView) {
        checkAndExposure(recyclerView);
    }

    public void onDataChanged(RecyclerView recyclerView) {
        checkAndExposure(recyclerView);
    }

    public void pageShow(RecyclerView recyclerView) {
        checkAndExposure(recyclerView);
    }

    public void pageHide(RecyclerView recyclerView) {

    }


    protected abstract String key(@NonNull Data data);

    private void checkAndExposure(RecyclerView recyclerView) {
        List<Data> dataList = checkAndGetExposureCard(recyclerView);
        if (dataList != null) {   //移除当前正在显示的
            for (Data data : dataList) {
                if (data != null) {
                    sExposures.remove(key(data));
                }
            }
        }
        if (!sExposures.isEmpty()) {  //剩下的就是需要结束曝光的
            Iterator<Map.Entry<String, WeakReference<Data>>> iterator = sExposures.entrySet().iterator();
            List<Data> endExposeList = new ArrayList<>();
            while (iterator.hasNext()) {
                Map.Entry<String, WeakReference<Data>> entry = iterator.next();
                if (entry != null) {
                    WeakReference<Data> ref = entry.getValue();
                    if (ref != null && ref.get() != null) {
                        endExposeList.add(ref.get());
                    }
                }
            }
            sExposures.clear();
            if (!endExposeList.isEmpty()) {
                onEndExpose(endExposeList);
            }
        }
        if (dataList != null) {
            onStartExpose(dataList);
            for (Data data : dataList) {
                if (data != null) {
                    sExposures.put(key(data), new WeakReference<>(data));
                }
            }
        }
    }

    protected abstract void onStartExpose(@NonNull List<Data> dataList);

    protected abstract void onEndExpose(@NonNull List<Data> dataList);

    private List<Data> checkAndGetExposureCard(RecyclerView recyclerView) {
        if (recyclerView == null) {
            return null;
        }
        List<Data> cardList = new ArrayList<>();
        for (int i = 0; i < recyclerView.getChildCount(); i++) {
            View child = recyclerView.getChildAt(i);
            if (child instanceof BaseCard) {
                BaseCard<Data> card = (BaseCard<Data>) child;
                if (enoughToExpose(card)) {
                    Data data = card.getData();
                    if (data != null) {
                        cardList.add(data);
                    }
                }
            }
        }
        return cardList;
    }

    /**
     * 子类可以重新曝光条件
     *
     * @param card
     * @return
     */
    protected boolean enoughToExpose(BaseCard<Data> card) {
        if (card.getHeight() > MIN_CARD_HEIGHT) {
            Rect rect = new Rect();
            if (card.getLocalVisibleRect(rect)) {
                if (rect.height() >= card.getHeight() / 2) {
                    return true;
                }
            }
        }
        return false;
    }

}
